package com.chaintor.demo.math;

import java.util.Vector;

public class BspBaseFunc {
    //关键点数
    private int _K;

    //曲线节点，一共有K+6个点
    private double[] _D;

    //基础函数1
    private double f1func(int k,double d){
        if (k <= _K+4) {
            if (_D[k-1] <= d  && d < _D[k]){
                return 1.0;
            }
        }else{
            if (_D[k-1] <= d  && d <= _D[k]){
                return 1.0;
            }
        }
        return 0;
    }
    //基础函数2
    private double f2func(int k,double d){
        double d1 ,d2;
        int r = 2;
        if (_D[k-1+r-1]-_D[k-1] == 0) {
            d1 = 0;
        }else{
            d1 = f1func(k,d)*(d-_D[k-1])/(_D[k-1+r-1]-_D[k-1]);
        }
        if (_D[k-1+r]-_D[k-1+1] == 0 ){
            d2 = 0;
        }else{
            d2 = f1func(k+1,d)*(_D[k-1+r]-d)/(_D[k-1+r]-_D[k-1+1]);
        }
        return d1+d2;
    }
    //基础函数3
    private double f3func(int k,double d){
        double d1 ,d2;
        int r = 3;
        if (_D[k-1+r-1]-_D[k-1] == 0) {
            d1 = 0;
        }else{
            d1 = f2func(k,d)*(d-_D[k-1])/(_D[k-1+r-1]-_D[k-1]);
        }
        if (_D[k-1+r]-_D[k-1+1] == 0 ){
            d2 = 0;
        }else{
            d2 = f2func(k+1,d)*(_D[k-1+r]-d)/(_D[k-1+r]-_D[k-1+1]);
        }
        return d1+d2;
    }
    //基础函数4
    private double f4func(int k,double d){
        double d1 ,d2;
        int r = 4;
        if (_D[k-1+r-1]-_D[k-1] == 0) {
            d1 = 0;
        }else{
            d1 = f3func(k,d)*(d-_D[k-1])/(_D[k-1+r-1]-_D[k-1]);
        }
        if (_D[k-1+r]-_D[k-1+1] == 0 ){
            d2 = 0;
        }else{
            d2 = f3func(k+1,d)*(_D[k-1+r]-d)/(_D[k-1+r]-_D[k-1+1]);
        }
        return d1+d2;
    }

    //基函数4的两阶导数
    public double f4Derivative(int k,double d){
        double d1,d2,d3,d4;
        if ((_D[k-1+3]-_D[k-1])*(_D[k-1+2]-_D[k-1]) == 0 ){
            d1 = 0.0;
        }else {
            d1 = 6.0 / ((_D[k - 1 + 3] - _D[k - 1]) * (_D[k - 1 + 2] - _D[k - 1])) * f2func(k, d);
        }
        if ((_D[k - 1 + 3] - _D[k - 1]) * (_D[k - 1 + 3] - _D[k - 1 + 1]) == 0 ){
            d2 = 0.0;
        }else {
            d2 = 6.0 / ((_D[k - 1 + 3] - _D[k - 1]) * (_D[k - 1 + 3] - _D[k - 1 + 1])) * f2func(k + 1, d);
        }
        if ((_D[k - 1 + 4] - _D[k - 1 + 1]) * (_D[k - 1 + 3] - _D[k - 1 + 1]) == 0 ){
            d3 = 0.0;
        }else {
            d3 = 6.0 / ((_D[k - 1 + 4] - _D[k - 1 + 1]) * (_D[k - 1 + 3] - _D[k - 1 + 1])) * f2func(k + 1, d);
        }
        if ((_D[k - 1 + 4] - _D[k - 1 + 1]) * (_D[k - 1 + 4] - _D[k - 1 + 2]) == 0){
            d4 = 0.0;
        }else {
            d4 = 6.0 / ((_D[k - 1 + 4] - _D[k - 1 + 1]) * (_D[k - 1 + 4] - _D[k - 1 + 2])) * f2func(k + 2, d);
        }
        return d1-d2-d3+d4;
    }

    public BspBaseFunc(double[] keys){
        _K = keys.length;
        //扩充曲线节点
        _D = new double[_K+6];
        _D[0] = _D[1]= _D[2] = keys[0];
        for (int i=0;i<keys.length;i++){
            _D[i+3] =  keys[i];
        }
        _D[_K+3] =  _D[_K+4] = _D[_K+5] = keys[_K-1];
    }

}
